﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GodPl.GameObjects.Creatures;
using GodPl.GameObjects.Creatures.Actions;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace GodPl.GameObjects
{
    public static class IObstacleExtensions
    {
        public static Vector2 GetForce(this IObstacle source, GameObject recipient)
        {
            return source.GetForce(recipient, AMoveTowards.RepelFactor, false);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="recipient"></param>
        /// <param name="attractFactor">
        /// Factor by which to scale the gravitational force.
        /// Attracting if positive, repelling if negative.</param>
        /// <returns></returns>
        public static Vector2 GetForce(this IObstacle source, GameObject recipient, float attractFactor, bool isConstant)
        {
            GameObject sourceG = (GameObject)source;

            float dist = 0;
            Vector2 direction = new Vector2();

            switch (source.GravityType)
            {
                case ObstacleGravityType.Point:
                    dist = recipient.DistanceTo(sourceG);
                    direction = Vector2.Normalize(sourceG.Position - recipient.Position);
                    break;

                case ObstacleGravityType.Horizontal:
                    dist = sourceG.Position.Y - recipient.Position.Y;
                    direction = new Vector2(0, (dist > 0 ? 1.0f : 0.0f));
                    dist = Math.Abs(dist);
                    break;
                    
                case ObstacleGravityType.Vertical:
                    dist = Math.Abs(sourceG.Position.X - recipient.Position.X);
                    direction = new Vector2((dist > 0 ? 1.0f : 0.0f), 0);
                    dist = Math.Abs(dist);
                    break;
            }

            float divisor = isConstant ? 1f : (float)Math.Pow(dist, 2);
            float radius;
            if (source.GravityType == ObstacleGravityType.Point)
            {
                radius = sourceG.BoundingRectangle.DiagonalLength() / 2;
            }
            else
            {
                radius = 50;
            }

            if (dist < radius)
            {
                attractFactor *= 10;
            }

            return (direction * (float)attractFactor * (float)Math.Pow(radius, 2)
                * (1f / divisor));
        }
    }
}
